package com.geping.etl.common.service.impl;

import com.alibaba.fastjson.JSON;
import com.geping.etl.common.entity.Sys_User;
import com.geping.etl.common.entity.Sys_UserAndOrgDepartment;
import com.geping.etl.common.repository.Report_InfoRepository;
import com.geping.etl.common.service.GroupService;
import com.geping.etl.common.service.Sys_UserAndOrgDepartmentService;
import com.geping.etl.common.service.Sys_UserService;
import com.geping.etl.common.vo.ResponseVo;
import com.geping.etl.utils.EnvUitl;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.sql.SQLSyntaxErrorException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xuanhao.ji
 * @date 2022/2/9
 */

@Slf4j
@Service
public class GroupServiceImpl implements GroupService {

    @Autowired
    private Sys_UserService sysUserService;

    @Autowired
    private Report_InfoRepository report_infoRepository;

    @Autowired
    private Sys_UserAndOrgDepartmentService sys_UserAndOrgDepartmentService;


    private List<Sys_User> lists = null;

    @Autowired
    private EntityManager manager;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Override
    public ResponseVo dealWithInfo(String code, String info, String subjectId) {
        log.info("start dealWithInfo code = {}, info = {}, subjectId = {}", code, info, subjectId);
        //分组信息判断
        ResponseVo responseVo = verityInfo(info,subjectId);
        if (responseVo.isResult()==false) return responseVo;
        Map<String, List<String>> groupMap =  null;
        if (StringUtils.isNotBlank(info.trim())) groupMap = neatenData(info);
        try {
            String mapString = "";
            if (groupMap != null) mapString = JSON.toJSONString(groupMap);
            if (!subjectId.trim().equals("8")) report_infoRepository.saveGroupInfo(code.toUpperCase(), mapString, subjectId);
            else {
                Map<String, Map<String, List<String>>> sidMap = groupBySid(groupMap, subjectId);
                if (sidMap.size() > 0) mapString = JSON.toJSONString(sidMap);

                log.info("保存分组信息 code = {}, sidString = {}, subject = {}", code, mapString, subjectId);
                report_infoRepository.saveGroupInfo8(code.toUpperCase(), mapString, subjectId, "数据管理");
            }
        }catch (Exception e) {
            log.error("method dealWithInfo error -> {}",e);
            return new ResponseVo(false,"系统错误，请联系管理员");
        }
        log.info("end dealWithInfo ");
        return new ResponseVo(true,"分组成功");
    }

    public Map<String, List<String>> neatenData(String info) {
        Map<String, List<String>> groupMap = new HashMap<>();
        String[] gInfos = info.split(";");
        //数据处理
        for (String gInfo : gInfos) {
            String[] strs = gInfo.split("-");
            String groupName = strs[0] == null ? "" : strs[0].trim();
            String username = strs[1] == null ? "" : strs[1].trim();
            if (groupMap.get(groupName) == null) {
                List<String> users = new ArrayList<>();
                users.add(username);
                groupMap.put(groupName, users);
            }else {
                groupMap.get(groupName).add(username);
            }
        }
        return groupMap;
    }

    public Map<String, Map<String, List<String>>> groupBySid(Map<String, List<String>> groupMap, String subjectId) {

        log.info("start groupBySid groupMap = {} , subject = {}", groupMap, subjectId);
        Map<String, Map<String, List<String>>> sidMap = new HashMap<>();
        if (groupMap == null) return sidMap;
        Set<String> sets = groupMap.keySet();
        for (String set : sets) {
            List<String> lids = groupMap.get(set);
            Sys_User userInfo = lists.stream().filter(sys_user -> sys_user.getLoginId().equals(lids.get(0))).collect(Collectors.toList()).get(0);
            String sid = userInfo.getEndDate() == null? "":userInfo.getEndDate();
            if (!"on".equals(EnvUitl.props.getProperty("user_more_org"))) sid = userInfo.getOrgId();
            else sid = userInfo.getEndDate();
            if (StringUtils.isNotBlank(sid)) {
                String orgId = null;
                if ("on".equals(EnvUitl.props.getProperty("user_more_org"))) {
                    Map<String, String> tempOrgMap = JSON.parseObject(sid, Map.class);
                    orgId = tempOrgMap.get(subjectId);
                } else  {
                    orgId = sid;
                }
                if (orgId != null) {
                    if (sidMap.get(orgId) == null) {
                        Map<String, List<String>> tempMap = new HashMap<>();
                        tempMap.put(set, lids);
                        sidMap.put(orgId, tempMap);
                    } else {
                        Map<String, List<String>> tempMap = sidMap.get(orgId);
                        tempMap.put(set, lids);
                        sidMap.put(orgId, tempMap);
                    }
                }
            } else {
                throw new RuntimeException(userInfo.getLoginId()+"无机构信息，请先分配机构");
            }
        }
        log.info("end groupBySid sidMap = {}", sidMap);
        return sidMap;

    }
    public ResponseVo verityInfo(String info, final String subjectId) {
        try {
            log.info("==starts to verify data correctness==");
            lists = sysUserService.findAllSysUser();
            //空数据直接返回
            if (StringUtils.isBlank(info.trim())) return new ResponseVo(true, "校验成功");

            Map<String, List<String>> groupMap = neatenData(info);

            //校验

            //标记组中是否存在不分部门人员
            boolean isHaveNDept = false;

            List<Sys_User> allUsers = new ArrayList<>();
            //同组同部门
            Set<String> set = groupMap.keySet();
            StringBuffer buffer = new StringBuffer();
            for (String s : set) {
                final List<String> userList = groupMap.get(s);
                List<Sys_User> sys_users = lists.stream().filter(sys_user -> userList.contains(sys_user.getLoginId())).collect(Collectors.toList());
                String user_more_dept = EnvUitl.props.getProperty("user_more_dept").equalsIgnoreCase("on") ? "on" : "off";
                if ("on".equals(user_more_dept)) {
                    for (int i = 0; i < sys_users.size(); i++) {
                        Sys_User sys_user = sys_users.get(i);
                        String systemdept = sys_user.getSystemDept();
                        if (StringUtils.isNotBlank(systemdept)) {
                            Map<String, String> map = JSON.parseObject(systemdept, Map.class);
                            String isDept = map.get(subjectId);
                            sys_user.setIsDept(isDept);
                        }
                    }
                }

                allUsers.addAll(sys_users);

                boolean one = false;
                boolean two = false;

                String user_more_org = EnvUitl.props.getProperty("user_more_org").equalsIgnoreCase("on") ? "on" : "off";
                if ("on".equals(user_more_org)) {
                    List<String> endDates = sys_users.stream().map(sys_user -> sys_user.getEndDate() == null ? "":sys_user.getEndDate()).collect(Collectors.toList());
                    for (String endDate : endDates) {
                        if (StringUtils.isBlank(endDate)) {
                            one = true;
                        } else {
                            two = true;
                        }
                    }
                    if (one & two) return new ResponseVo(false, "组别" + s + "，存在不同机构的审核人员");

                    List<Map<String, String>> mapList = new ArrayList<>();
                    for (String endDate : endDates) {
                        if (StringUtils.isNotBlank(endDate)) {
                            Map<String, String> map = JSON.parseObject(endDate, Map.class);
                            mapList.add(map);
                        }
                    }
                    List<String> orgs = mapList.stream().map(map -> map.get(subjectId) == null ? "" : map.get(subjectId)).distinct().collect(Collectors.toList());
                    if (orgs.size() > 1) return new ResponseVo(false, "组别" + s +",存在不同机构的审核人员");

                    if (orgs.size() == 1 && StringUtils.isBlank(orgs.get(0))) return new ResponseVo(false, "组别"+ s +",组内存在审核人员不存在机构信息");
                } else {
                    List<String> orgs = sys_users.stream().map(sy -> sy.getOrgId() == null ? "" : sy.getOrgId()).distinct().collect(Collectors.toList());
                    if (orgs.size() > 1) return new ResponseVo(false, "组别" + s +",存在不同机构的审核人员");

                    if (orgs.size() == 1 && StringUtils.isBlank(orgs.get(0))) return new ResponseVo(false, "组别"+ s +",组内存在审核人员不存在机构信息");
                }

                if (sys_users.stream().map(Sys_User::getIsDept).distinct().collect(Collectors.toList()).size() > 1)
                    return new ResponseVo(false,"组别"+s+",同时存在分部门和不分部门的审核人员");

                if (sys_users.stream().map(Sys_User::getIsDept).distinct().collect(Collectors.toList()).get(0).equals("Y")) {
                    if (sys_users.stream().map(Sys_User::getDepartId).distinct().collect(Collectors.toList()).size() > 1)
                        return new ResponseVo(false,"组别:"+s+",存在不同部门的审核人员");
                } else {
                    isHaveNDept = true;
                }

                if (userList.size() != userList.stream().distinct().collect(Collectors.toList()).size()) {
                    buffer.append("[");
                    buffer.append(s);
                    buffer.append(",");
                }
            }
            if (buffer.length() > 0) {
                buffer.substring(0,buffer.length()-1);
                buffer.append("]");
                buffer.append("组内存在相同的审核人员");
                return new ResponseVo(false, buffer.toString());
            }

            //如果某个组存在全部为不分部门的审核人员则，不需校验部门是否齐全

//            if (!isHaveNDept) {
//                List<String> allDepartments = lists.stream().map(Sys_UserAndOrgDepartment::getDepartmentname).distinct().collect(Collectors.toList());
//                List<String> useDepartments = allUsers.stream().map(Sys_UserAndOrgDepartment::getDepartmentname).distinct().collect(Collectors.toList());
//                allDepartments.removeAll(useDepartments);
//                if (allDepartments.size() > 0) {
//                    buffer.append("[");
//                    for (String allDepartment : allDepartments) {
//                        buffer.append(allDepartment);
//                        buffer.append(",");
//                    }
//                    buffer.substring(0,buffer.length()-1);
//                    buffer.append("]");
//                    buffer.append("部门不存在分组");
//                    return new ResponseVo(false,buffer.toString());
//                }
//            }

            //校验是否存在同一个审核人员出现在多组
            List<String> allLoginCname = allUsers.stream().map(sys_user -> sys_user.getLoginId()).collect(Collectors.toList());
            List<String> disLoginCname = allLoginCname.stream().distinct().collect(Collectors.toList());
            for (String s : disLoginCname) {
                allLoginCname.remove(s);
            }
            if (allLoginCname.size() > 0) {
                buffer.append("[");
                for (String s : allLoginCname) {
                    buffer.append(s);
                    buffer.append(",");
                }
                buffer.substring(0,buffer.length()-1);
                buffer.append("]");
                buffer.append("审核人员在多组中存在");
                return new ResponseVo(false,buffer.toString());
            }

        }catch (Exception e) {
            log.error("method verityInfo error -> {}",e);
            return new ResponseVo(false,"校验阶段系统错误，请联系管理员");
        }
        log.info("==end to verify data correctness==");
        return new ResponseVo(true,"校验成功");
    }
}
